package com.blockmeta.bbs.businesslibrary.net.retrofit;

import com.google.gson.Gson;

import org.json.JSONObject;

import java.io.IOException;
import java.io.Reader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.nio.charset.Charset;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

public class BTCConverterFactory<T> extends Converter.Factory
{
	private static final MediaType JSON_MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
	private static final Charset UTF_8 = Charset.forName("UTF-8");

	public static BTCConverterFactory create() {
		return create(new Gson());
	}

	public static BTCConverterFactory create(Gson gson) {
		return new BTCConverterFactory(gson);
	}

	private final Gson gson;

	private BTCConverterFactory(Gson gson) {
		if (gson == null) throw new NullPointerException("gson == null");
		this.gson = gson;
	}

	@Override
	public Converter<ResponseBody, ?> responseBodyConverter(
			final Type type, Annotation[] annotations, Retrofit retrofit)
	{
		if (String.class.equals(type))
		{
			return new Converter<ResponseBody, String>()
			{
				@Override
				public String convert(ResponseBody value) throws IOException
				{
					return value.string();
				}
			};
		}
		else
		{
			return new Converter<ResponseBody, String>()
			{
				@Override
				public String convert(ResponseBody value) throws IOException
				{
					Reader reader = value.charStream();

					try {
						return gson.fromJson(reader, type);
					} finally {
						try {
							if (reader != null)
							{
								reader.close();
							}
						} catch (IOException ignored) {
						}
					}
				}
			};
		}
	}

	@Override
	public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit)
	{
		if (String.class.equals(type) || JSONObject.class.equals(type))
		{
			return new Converter<String, RequestBody>()
			{
				@Override
				public RequestBody convert(String value) throws IOException
				{
					return RequestBody.create(JSON_MEDIA_TYPE, value.toString());
				}
			};
		}
		return new Converter<Object, RequestBody>()
		{
			@Override
			public RequestBody convert(Object value) throws IOException
			{
				String body = gson.toJson(value);
				return RequestBody.create(JSON_MEDIA_TYPE, body);
			}
		};
	}
}
